package czy.demo.controller;


import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Api(tags = "Redis Hash操作控制器")
@RestController
@RequestMapping("/redis/hash")
public class HashController {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @GetMapping("/exists/{key}/{hashKey}")
    @ApiImplicitParams({
       @ApiImplicitParam(name = "key", value= "Redis键",type = "path",required = true),
       @ApiImplicitParam(name = "hashKey",value = "Redis键",type = "path",required = true)
    })
    @ApiOperation(value = "指定hashKey的值是否存在",produces = "text/plain",response = Boolean.class)
    public boolean has(@PathVariable String key, @PathVariable String hashKey){
        return this.redisTemplate.opsForHash().hasKey(key,hashKey);
    }

    /**
     * 获取指定hash下键值对的数量
     */
    @GetMapping("/size/{key}")
    public long size(@PathVariable String key){
        return this.redisTemplate.<String,Object>opsForHash().size(key);
    }

    /**
     * 指定hash中key的集合
     */
    @GetMapping("/keys/{key}")
    public Set<String> keys(@PathVariable String key){
        return this.redisTemplate.<String,Object>opsForHash().keys(key);
    }

    /**
     * 指定hash的value列表
     */
    @GetMapping("/values/{key}")
    public List<Object> values(@PathVariable String key){
        return this.redisTemplate.opsForHash().values(key);
    }

    /**
     * 获取指定hash的所有键值对映射
     */
    @GetMapping("/entries/{key}")
    public Map<String,Object> entries(@PathVariable String key){
        return this.redisTemplate.<String,Object>opsForHash().entries(key);
    }

    /**
     * 使用指定hashKey的模式，以及数量来查找元素
     * @param key：hash名称
     * @param count：获取数量
     * @param pattern：hashKey匹配的模式
     * @return 查找到的键值对映射
     */
    @GetMapping("/entries/{key}/{count}/{pattern}")
    public Map<String,Object> scan(@PathVariable String key,@PathVariable long count,@PathVariable String pattern){
        ScanOptions options = new ScanOptions.ScanOptionsBuilder().count(count).match(pattern).build();
        Cursor<Map.Entry<String,Object>> cursor  = this.redisTemplate.<String,Object>opsForHash().scan(key,options);
        Map<String,Object> map = new HashMap<>();
        cursor.open();
        while(cursor.hasNext()){
            map.put(cursor.next().getKey(),cursor.next().getValue());
        }
        return map;
    }

    /**
     * 获取指定hash指定key的元素值
     */
    @GetMapping("/{key}/{hashkey}")
    public Object get(@PathVariable String key,@PathVariable String hashkey){
        return this.redisTemplate.<String,Object>opsForHash().get(key,hashkey);
    }

    /**
     * 插入新数据，设置指定哈希，指定key的元素值
     */
    @PostMapping("/{key}/{hashkey}")
    public Object create(@PathVariable String key,@PathVariable String hashkey,@RequestBody Object Object){
        /* 如果hashkey不存在才插入 */
        this.redisTemplate.<String,Object>opsForHash().putIfAbsent(key,hashkey,Object);
        return Object;
    }

    /**
     * 更新指定hash，指定hashKey的值
     */
    @PutMapping("/{key}/{hashkey}")
    public Object update(@PathVariable String key,@PathVariable String hashkey,@RequestBody Object Object){
        /* 不管指定hashKey是否存在，都重新设置值 */
        this.redisTemplate.<String,Object>opsForHash().put(key,hashkey,Object);
        return Object;
    }
    /**
     * 删除指定hash，指定key的元素值
     */
    @DeleteMapping("/{key}/{hashkey}")
    public long delete(@PathVariable String key,@PathVariable String hashkey){
        return this.redisTemplate.<String,Object>opsForHash().delete(key,hashkey);
    }


}
